<!-- Uses base code from shadcn-vue Input component and extends it's functionality-->
<template>
  <div
    ref="inputContainerRef"
    :class="
      cn(
        'group/input relative rounded-lg p-[2px] transition-all duration-300 ease-in-out',
        props.containerClass,
      )
    "
    :style="{ background: containerBg }"
    @mouseenter="() => (visible = true)"
    @mouseleave="() => (visible = false)"
    @mousemove="handleMouseMove"
  >
    <input
      v-bind="$attrs"
      v-model="modelValue"
      :class="
        cn(
          `relative z-10 flex h-10 w-full border-none bg-gray-50 dark:bg-zinc-800 text-black dark:text-white shadow-input rounded-md px-3 py-2 text-sm  file:border-0 file:bg-transparent 
            file:text-sm file:font-medium placeholder:text-neutral-400 dark:placeholder-text-neutral-600 
            focus-visible:outline-none focus-visible:ring-[2px]  focus-visible:ring-neutral-400 dark:focus-visible:ring-neutral-600
             disabled:cursor-not-allowed disabled:opacity-50
             dark:shadow-[0px_0px_1px_1px_var(--neutral-700)]
             group-hover/input:shadow-none transition duration-400`,
          props.class,
        )
      "
    />
  </div>
</template>

<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
import { useVModel } from '@vueuse/core'
import { ref, computed } from 'vue'

defineOptions({
  inheritAttrs: false,
})

const props = defineProps<{
  defaultValue?: string | number
  modelValue?: string | number
  class?: HTMLAttributes['class']
  containerClass?: HTMLAttributes['class']
}>()

const emits = defineEmits<{
  (e: 'update:modelValue', payload: string | number): void
}>()

const modelValue = useVModel(props, 'modelValue', emits, {
  passive: true,
  defaultValue: props.defaultValue,
})

const inputContainerRef = ref<HTMLDivElement | null>(null)
const mouse = ref<{ x: number; y: number }>({ x: 0, y: 0 })
const radius = 100
const visible = ref(false)

const containerBg = computed(() => {
  return `
    radial-gradient(
      ${visible.value ? radius + 'px' : '0px'} circle at ${mouse.value.x}px ${mouse.value.y}px,
      rgba(59, 130, 246, 0.3),
      transparent 80%
    )
  `
})

function handleMouseMove({ clientX, clientY }: MouseEvent) {
  if (!inputContainerRef.value) return

  const { left, top } = inputContainerRef.value.getBoundingClientRect()
  mouse.value = { x: clientX - left, y: clientY - top }
}
</script>

<style scoped>
input {
  box-shadow:
    0px 2px 3px -1px rgba(0, 0, 0, 0.1),
    0px 1px 0px 0px rgba(25, 28, 33, 0.02),
    0px 0px 0px 1px rgba(25, 28, 33, 0.08);
}
</style>
